package util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Random;

import org.apache.commons.lang3.ArrayUtils;

/**
 * Utility class for most common reusable functions
 * @author pradeeph
 *
 */
public class CommonUtil {
	
	private static final String DEFALT_RETURN_DATE_FORMAT = "MM/dd/yyyy";
	
	/**
	 * to get the next integer number within the given range.
	 * 
	 * @param aStart - beginning of the range
	 * @param aEnd - ending of the range
	 * @return int
	 */
	public static int nextIntInRange(int aStart, int aEnd) {
		return nextIntInRange(aStart,aEnd,new Random());
	}
	
	/**
	 * to get the next integer number within the given range.
	 * 
	 * @param aStart - beginning of the range
	 * @param aEnd - ending of the range
	 * @param aRandom - Random Object
	 * @return int
	 */
	public static int nextIntInRange(int aStart, int aEnd, Random aRandom) {
		if (aStart > aEnd) {
			throw new IllegalArgumentException("Cannot draw random int from invalid range [" + aStart + ", " + aEnd + "].");
		}
		// get the range, casting to long to avoid overflow problems
		long range = (long) aEnd - (long) aStart + 1;
		// compute a fraction of the range, 0 <= frac < range
		long fraction = (long) (range * aRandom.nextDouble());
		//System.out.println((int) (fraction + aStart));
		return (int) (fraction + aStart);
	}
	
	/**
	 * to get the current date in string
	 * 
	 * @return
	 * @throws ParseException
	 */
	public static String getCurrentStringDate() throws ParseException
	{
		return getFormatedDate(getCurrentDate(), DEFALT_RETURN_DATE_FORMAT);
	}
	
	/**
	 * to get the sql safe date string
	 * 
	 * @param strDate - input date string
	 * @param srcDateFormat - inputed date format
	 * @return String - sql safe date
	 * @throws ParseException
	 */
	public static String getFormatedDate(String strDate, String srcDateFormat) throws ParseException
	{
		return getFormatedDate(strDate, srcDateFormat, DEFALT_RETURN_DATE_FORMAT);
	}
	
	/**
	 * to get the sql safe date string
	 * 
	 * @param strDate - input date string
	 * @param srcDateFormat - inputed date format
	 * @return String - sql safe date
	 * @throws ParseException
	 */
	public static String getFormatedDate(String strDate, String srcDateFormat, String targetedDateFormat) throws ParseException
	{
		SimpleDateFormat df = getDateFormat(srcDateFormat);
		
		// parse the string into Date object
        Date date = null;
        
        if( isNotEmpty(strDate))
        {
        	date = df.parse(strDate);
        }
        
		return getFormatedDate(date, targetedDateFormat);
	}
	
	/**
	 * to get the date object
	 */
	public static Date getCurrentDate()
	{
		return Calendar.getInstance().getTime();		
	}
	
	/**
	 * to get the current year
	 */
	public static int getCurrentYear()
	{
		return Calendar.getInstance().get(Calendar.YEAR);		
	}
	
	/**
	 * to get the sql safe date string
	 * 
	 * @param date - date object
	 * @return String - sql safe date
	 * @throws ParseException
	 */
	public static String getFormatedDate(Date date) throws ParseException
	{
		SimpleDateFormat df = getDateFormat(null);
		
		return df.format(date);		
	}
	
	/**
	 * to get the sql safe date string
	 * 
	 * @param date - date object
	 * @param dateFormat - inputed date format
	 * @return String - sql safe date
	 * @throws ParseException
	 */
	public static String getFormatedDate(Date date, String dateFormat) throws ParseException
	{
		SimpleDateFormat df = getDateFormat(dateFormat);
		
		return df.format(date);		
	}
	
	/**
	 * to get the SimpleDateFormat object for the given date format, 
	 * 		in case of empty date format it will return default SimpleDateFormat object.
	 * 
	 * @param dateFormat
	 * @return
	 */
	public static SimpleDateFormat getDateFormat(String dateFormat)
	{
		if( isEmpty(dateFormat) )
		{
			dateFormat = DEFALT_RETURN_DATE_FORMAT;
		}
		
		return new SimpleDateFormat(dateFormat);
	}	
	
	/**
	 * To check nullability or emptiness of the object 
	 * Returns true if, and only if, object is null or length()/size() is 0. 
	 * 
	 * @param obj
	 * @return
	 */
	public static boolean isEmpty(Object obj) 
	{
		if (obj == null) 
		{
			return true;
		}
		else if (obj instanceof String && ((String) obj).length() == 0) 
		{
			return true;
		}
		else if (obj instanceof Collection<?> && ((Collection<?>) obj).size() == 0)
		{
			return true;
		}
		else if (obj instanceof Map && ((Map<?, ?>) obj).size() == 0)
		{
			return true;
		}
		
		return false;
	}
	
	/**
	 * To check nullability or emptiness of the object 
	 * Returns true if , and only if, object is not empty. 
	 * 
	 * @param text
	 * @return
	 */
	public static boolean isNotEmpty(String text)
	{
		return !isEmpty(text);		
	}
	
	/**
	 * To remove elements from array
	 * 
	 * @param input
	 * @param deleteElement
	 * @return
	 */
	public static String[] removeElements(String[] input, String... deleteElement) 
	{
	    List<String> result = new LinkedList<String>();

	    for(String item : input)
	    {
	    	if(!ArrayUtils.contains(deleteElement,item))
	        {
	        	result.add(item);
	        }
	    }
	        
	    return result.toArray(new String[result.size()]);
	}

	
	public static void main(String[] args) {
//		System.out.println(CommonUtil.isEmpty(null));
//		System.out.println(CommonUtil.isEmpty(""));
//		System.out.println(CommonUtil.isEmpty(new ArrayList()));
//		System.out.println(CommonUtil.isEmpty(new HashMap()));			
	}
}
